﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Flurl.Http;
using Newtonsoft.Json.Linq;
using Pay.Core;
using Pay.DTO;
using Pay.DTO.hxdata;
using Pay.IService;
using Pay.TO;

namespace Pay.Service {
	public class HxDataPayService : ServiceBase2, IPayService, IDisposable {
		private IUnitOfWork _iUnitOfWork;
		private ISettingService _iSettingService;
		private IMerchantService _iMerchantService;
		private IChargeService _iChargeService;
		private IRegionService _iRegionService;
		private ITransferService _iTransferService;
		private IProfitDayService _iProfitDayService;
		private IBillService _iBillService;
		private IPayHtmlService _iPayHtmlService;
		private HxDataSign _hxDataSign;

		public HxDataPayService(IUnitOfWork iUnitOfWork, ISettingService iSettingService,
						IMerchantService iMerchantService, IChargeService iChargeService, IRegionService iRegionService,
						ITransferService iTransferService, IProfitDayService iProfitDayService, IBillService iBillService,
						IPayHtmlService iPayHtmlService) : base(iUnitOfWork) {
			_iUnitOfWork = iUnitOfWork;
			_iSettingService = iSettingService;
			_iMerchantService = iMerchantService;
			_iChargeService = iChargeService;
			_iRegionService = iRegionService;
			_iTransferService = iTransferService;
			_iProfitDayService = iProfitDayService;
			_iBillService = iBillService;
			_iPayHtmlService = iPayHtmlService;
			_hxDataSign = new HxDataSign();
		}

		#region 扫码的
		/// <summary>
		/// 生成二维码扫码请求通道封装
		/// </summary>
		/// <returns>The pay gateway.</returns>
		/// <param name="model">Model.</param>
		/// <typeparam name="T">The 1st type parameter.</typeparam>
		public Task<native_result> NativePay(native_model model) {
			throw new NotImplementedException();
		}
		#endregion

		#region 支付异步通知
		/// <summary>
		/// 回调支付通知，商户返回OK，不再回调了，流程是先调用ChargeService的NotifyOrder，
		/// 返回值判断是调用哪个通道，再调用本方法，最后调用ChargeService的Update
		/// </summary>
		/// <returns>The notify.</returns>
		/// <param name="order_no">Order.</param>
		public async Task<string> Notify(string merchant_no, string order_no) {
			string result = string.Empty;
			charge_dto order = _iChargeService.Get(merchant_no, order_no);
			try {
				var data = new pay_notity {
					tran_amount = ((int)(order.order_amount * 100)).ToString(), order_no = order.order_no, transaction_no = order.pay_info.transaction_no,
					pay_time = order.pay_info.pay_time.HasValue ? order.pay_info.pay_time.Value : order.order_time,
					status = (order.status == ChargeStatus.Finish ? 1 : 2)
				};
				//失败的要再查询通道判断是否真失败,处理掉单
				if (order.status != ChargeStatus.Finish) {
					var pay_model = new hx_head_base();
					//pay_model.client_trans_id = order.order_no;
					pay_model.client_trans_id = order.pay_info.pay_no;
					pay_model.trans_timestamp = DateTime.Now.ToUnix();
					pay_model.data = data.ToJson();
					var resultApi = await _hxDataSign.PayGateway<hx_query_result>(pay_model);
					if (resultApi != null) {
						if (resultApi.resp_code == "000000" && resultApi.data.resp_code == "PAY_SUCCESS" /*&& resultApi.data.withdrawals_status == "WITHDRAWALS_SUCCESS"*/) {
							data.status = 1;
							var pay_time = DateTime.Now;
							_iChargeService.FailOrUnConfirmToSuceess(merchant_no, order.order_no, pay_time);
						}
					}
				}
				data.result_msg = (data.status == 1 ? "支付成功" : order.fail);
				if (string.IsNullOrEmpty(order.notify)) return "OK";
				var notify_result = await order.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveJson<ResultMessage<string>>();
				result = notify_result.data;
				var log = IocHelper.Get<ILogHelper>("info");
				log.Info(order.order_no + ":" + notify_result.ToJson());
			} catch (Exception ex) {
				var log = IocHelper.Get<ILogHelper>("info");
				log.Error("订单通道查询异常:" + order.order_no);
				string message = string.Format("消息类型：{0}\r\n消息内容：{1}\r\n引发异常的方法：{2}\r\n引发异常源：{3}"
								, ex.GetType().Name, ex.Message, ex.TargetSite, ex.Source + ex.StackTrace);
				log.Error(message);
			}
			return result;
		}

		/// <summary>
		/// 代付通知－不可用
		/// </summary>
		/// <returns>The transfer.</returns>
		/// <param name="order_no">Order.</param>
		public Task<string> NotifyTransfer(string merchant_no, string order_no) {
			throw new NotImplementedException();
		}
		#endregion

		#region 实名、T0额度-不可用
		/// <summary>
		/// 查询代付T0额度
		/// </summary>
		/// <returns>The quota.</returns>
		/// <param name="merchant_no"></param>
		/// <param name="busiType">0：对公 1：对私</param>
		public Task<quota_result> Quota(string merchant_no, string busiType) {
			throw new NotImplementedException();
		}
		#endregion

		#region 快捷同卡同出
		/// <summary>
		/// 快捷支付
		/// </summary>
		/// <returns>The receive.</returns>
		/// <param name="model">Model.</param>
		public async Task<quick_pay_result> QuickPay(quick_pay_model model) {
			string pay_code = model.pay_code;
			var setting = _iSettingService.Get();
			var binder = _iMerchantService.Get(model.bind_no);
            var binder_registers = _iMerchantService.GetRegisters(binder.id);
            string merCode = "";
			var register = binder_registers.FirstOrDefault(c => c.pay_channel == PayChannel.HxData);
			if (register == null) {
				var res = await MerchantRegister(binder.id, "A");
				if (res.result_code != 1000)
					return ApiResultToJson.Json<quick_pay_result>(res.result_msg, 2001);
				else
					merCode = res.merchant_no;
			} else
				merCode = register.merchant_no;
			//return ApiResultToJson.Json<quick_pay_result>("商户未进件，不能支付", 2001);
			model.settle_type = "T0";
            var binder_payments = _iMerchantService.GetPayments(binder.id);
            var payment = binder_payments.FirstOrDefault(c => c.payment.channel == model.pay_channel);
			var settle = payment.settles.First(c => c.settle_type == model.settle_type && c.code == pay_code);
			//同进件数据比较是否一致
			if (model.settle_fee / 100M != settle.settle)
				return ApiResultToJson.Json<quick_pay_result>("结算费与商户进件的结算费不同", 2001);
			if (model.fee != settle.fee)
				return ApiResultToJson.Json<quick_pay_result>("费率与商户进件的费率不同", 2001);
			if (model.pay_fee_amount != (int)Math.Ceiling(decimal.Parse(model.tran_amount) * model.fee))
				return ApiResultToJson.Json<quick_pay_result>("实扣费率金额不正确");
			//把商户请求转为通道请求消息
			var id = Guid.NewGuid().ToString("N");
			var notify = setting.site.api_url + "/hxdata_back_notify/" + id;
			var front_notify_url = model.front_notify;
			var dt = DateTime.Now.ToString("yyyyMMddHHmmss");
			var authinfo = binder.setting.auth_info;
			var data = new hx_quickpay_model {
				third_merchant_code = merCode, trans_time = dt, trans_date = dt.Substring(0, 8),
				counter_fee_t0 = model.settle_fee.ToString(), rate_t0 = (model.fee * 100).ToString("0.00"),
				trans_amount = model.tran_amount, operation_fee = ((int)(model.pay_fee_amount)).ToString(),
				family_name = model.account_name, id_card = model.id_card, pay_bank_no = model.account_no, mobile = model.mobile,
				payee_bank_no = authinfo.account_no, payee_bank_name = authinfo.bank_name,
				front_notify_url = front_notify_url, back_notify_url = notify
			};
			data.payee_bank_id = SetMerchantBankCode(authinfo.bank_code);
			data.pay_amount = (int.Parse(data.trans_amount) - int.Parse(data.operation_fee) - int.Parse(data.counter_fee_t0)).ToString();
			var pay_model = new hx_head_base();
			//注意要求订单号不得超过20位，以payno为订单号
			var charge = _iChargeService.AddByQuickPay(model);
			charge.pay_info.pay_no = model.order_no.Substring(0, 20);
			//pay_model.client_trans_id = model.order_no;
			pay_model.client_trans_id = charge.pay_info.pay_no;
			pay_model.trans_timestamp = DateTime.Now.ToUnix();
			pay_model.data = data.ToJson();
			var resultApi = await _hxDataSign.PayGateway<hx_quickpay_model_result>(pay_model);
			//调用通道执行并处理返回，请通道响应消息封装为平台响应商户消息
			if (resultApi != null) {
				if (resultApi.resp_msg.Contains("rate_t0 不一致")) {
					var register_model = register.ToDtoObject<merchant_register_model>();
					register_model.bind_no = model.bind_no;
					register_model.merchant_no = model.merchant_no;
					register_model.fee = model.fee;
					register_model.settle = model.settle_fee.ToString();
					var result = await MerchantRegister(register_model, "M");
					if (result.result_code == 1000)
						return ApiResultToJson.Json<quick_pay_result>("进件成功,请重新发起支付");
					else
						return ApiResultToJson.Json<quick_pay_result>(result.result_msg);
				}
				if (resultApi.resp_code == "000000") {
					//将HTML保存到mongodb
					var ok = _iPayHtmlService.Save(new pay_html_dto { id = id, html = resultApi.data.page_content, merchant_no = model.merchant_no, order_no = model.order_no, charge = charge.ToJson() });
					if (ok) {
						var requestUrl = setting.site.api_url + "/pay/hxdata_front/" + id;
						return ApiResultToJson.Json("鉴权成功，待确认支付", new quick_pay_result {
							order_no = model.order_no, protocol_no = "", request_url = requestUrl,
							pay_time = DateTime.Now, transaction_no = "", status = 3
						});
					} else
						return ApiResultToJson.Json<quick_pay_result>("支付页面加载失败");
				} else
					return ApiResultToJson.Json<quick_pay_result>(resultApi.resp_msg);
			}
			return ApiResultToJson.Json<quick_pay_result>("异常支付");
		}
		/// <summary>
		/// 快捷支付查询
		/// </summary>
		/// <returns>The pay query.</returns>
		/// <param name="model">Model.</param>
		public async Task<pay_notity> QuickPayQuery(refund_model_query model) {
			charge_dto order = null;
			var data = new pay_notity { status = 2, order_no = model.order_no };
			if (!string.IsNullOrEmpty(model.order_no)) order = _iChargeService.Get(model.merchant_no, model.order_no);
			if (order == null) {
				var obj = _iPayHtmlService.Get(model.merchant_no, model.order_no);
				if (obj != null) {
					var query_model = new hx_query_model { orig_tran_id = model.order_no };
					var pay_model = new hx_head_base();
					//pay_model.client_trans_id = model.order_no;
					var charge = obj.charge.ToObject<charge_dto>();
					pay_model.client_trans_id = charge.pay_info.pay_no;
					pay_model.trans_timestamp = DateTime.Now.ToUnix();
					pay_model.data = query_model.ToJson();
					var resultApi = await _hxDataSign.PayGateway<hx_query_result>(pay_model);
					if (resultApi != null) {
						if (resultApi.resp_code == "000000" && resultApi.data.resp_code == "PAY_SUCCESS" /*&& resultApi.data.withdrawals_status == "WITHDRAWALS_SUCCESS"*/) {
							data.status = 1; data.pay_time = obj.create_time; data.result_msg = "支付成功"; data.tran_amount = ((int)charge.amount * 100).ToString();
							var result = _iChargeService.PaySuceess(obj, data.order_no, data.pay_time);
							if (result > 0) {
								var notifyResult = await Notify(charge.merchant_no, model.order_no);
								_iPayHtmlService.Remove(obj.id);
							}
						} else {
							data.result_code = 1001; data.result_msg = resultApi.data.resp_msg;
							data.pay_time = obj.create_time; data.tran_amount = ((int)charge.amount * 100).ToString();
						}
					}
				} else {
					data.result_code = 1001; data.result_msg = "支付失败";
				}
			} else {
				data.status = order.status == ChargeStatus.Finish ? 1 : 2; data.pay_time = order.order_time; data.transaction_no = order.order_no;
				data.result_msg = order.status == ChargeStatus.Finish ? "支付成功" : "支付失败"; data.tran_amount = ((int)order.amount * 100).ToString();
				if (order.status != ChargeStatus.Finish) data.result_code = 1001;
			}
			return data;
		}
		#endregion

		#region 快捷支付－不可用
		/// <summary>
		/// 快捷支付鉴权成功后发短信
		/// </summary>
		/// <returns>The pay resms.</returns>
		/// <param name="model">model.</param>
		public Task<ApiResultMessage> QuickPaySendsms(quick_sendsms_model model) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 确认短信验证码
		/// </summary>
		/// <returns>The pay.</returns>
		/// <param name="model">model.</param>
		public Task<quick_pay_result> QuickPay(quick_sms_model model) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 快捷支付退款
		/// </summary>
		/// <returns>The pay refund.</returns>
		/// <param name="model">Model.</param>
		public Task<refund_result> QuickPayRefund(refund_model model) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 快捷支付退款查询,并将退款中的单处理为完成
		/// </summary>
		/// <returns>The pay refund.</returns>
		/// <param name="model">Model.</param>
		public Task<refund_result> QuickPayRefundQuery(refund_model_query model) {
			throw new NotImplementedException();
		}
		#endregion

		#region 网关支付-不可用
		/// <summary>
		/// 网关支付银行
		/// </summary>
		/// <returns>The pay bank.</returns>
		public List<type_setting> GatewayPayBank() {
			var banks = new List<type_setting>();
			banks.Add(new type_setting { value = "BOC", text = "中国银行" });
			banks.Add(new type_setting { value = "ABC", text = "中国农业银行" });
			banks.Add(new type_setting { value = "ICBC", text = "中国工商银行" });
			banks.Add(new type_setting { value = "CCB", text = "中国建设银行" });
			banks.Add(new type_setting { value = "BCOM", text = "交通银行" });
			banks.Add(new type_setting { value = "PSBC", text = "中国邮政储蓄银行" });
			banks.Add(new type_setting { value = "CMB", text = "招商银行" });
			banks.Add(new type_setting { value = "CMBC", text = "中国民生银行" });
			banks.Add(new type_setting { value = "CITIC", text = "中信银行" });
			banks.Add(new type_setting { value = "CEB", text = "中国光大银行" });
			banks.Add(new type_setting { value = "HXB", text = "华夏银行" });
			banks.Add(new type_setting { value = "GDB", text = "广发银行" });
			banks.Add(new type_setting { value = "CIB", text = "兴业银行" });
			banks.Add(new type_setting { value = "SPDB", text = "上海浦东发展银行" });
			banks.Add(new type_setting { value = "SPAB", text = "平安银行" });
			banks.Add(new type_setting { value = "SHB", text = "上海银行" });
			banks.Add(new type_setting { value = "BJB", text = "北京银行" });
			banks.Add(new type_setting { value = "HZCB", text = "杭州银行" });
			return banks;
		}

		/// <summary>
		/// 发起网关支付
		/// </summary>
		/// <returns>The receive.</returns>
		/// <param name="model">Model.</param>
		public Task<gateway_pay_result> GatewayPay(gateway_pay_model model) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 网关支付查询
		/// </summary>
		/// <returns>The pay query.</returns>
		/// <param name="model">Model.</param>
		public Task<pay_notity> GatewayPayQuery(refund_model_query model) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 网关支付退款
		/// </summary>
		/// <returns>The pay refund.</returns>
		/// <param name="model">Model.</param>
		public Task<refund_result> GatewayPayRefund(refund_model model) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 网关支付退款查询,并将退款中的单处理为完成
		/// </summary>
		/// <returns>The pay refund.</returns>
		/// <param name="model">Model.</param>
		public Task<refund_result> GatewayRefundQuery(refund_model_query model) {
			throw new NotImplementedException();
		}
		#endregion

		#region 代付,T+0转账-不可用
		/// <summary>
		/// 单笔代付
		/// </summary>
		/// <returns>The transfer.</returns>
		/// <param name="model">Model.</param>
		public Task<transfer_result> Transfer(apply_transfer model) {
			throw new NotImplementedException();
		}
		public Task<transfer_result> ReTransfer(long id) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 代付批处理:生成代付文件，将批号写入提现表，生成代付文件记录，并上传FTP，FTP成功调用代付通知，FTP失败提示手动上传，并去文件记录管理手动代付通知。
		/// </summary>
		/// <returns>The transfer.</returns>
		/// <param name="model">Model.</param>
		public Task<batch_transfer_result> Transfer(batch_transfer model) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 提交代付批处理报盘通知（平台后台用）
		/// </summary>
		/// <returns>The transfer.</returns>
		/// <param name="batchId">Batch Id.</param>
		public Task<int> TransferNotify(long batchId, string batchFileName, long merchant_id) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 提交代付批处理查询，返回回盘文件地址后，进行提现记录更新（平台后台用）
		/// </summary>
		/// <returns>The transfer.</returns>
		/// <param name="batchId">Batch Id.</param>
		/// <param name="noticeTranId">报盘通知交易流水号</param>
		public Task<int> TransferBack(long batchId, string noticeTranId, long merchant_id) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 单笔代付查询
		/// </summary>
		/// <returns>The query.</returns>
		/// <param name="model">Model.</param>
		public Task<transfer_result> TransferQuery(transfer_query model) {
			throw new NotImplementedException();
		}
		#endregion

		#region 代收,T+1转账-不可用
		/// <summary>
		/// 代收签约
		/// </summary>
		/// <returns>The receive.</returns>
		/// <param name="model">Model.</param>
		public Task<ApiResultMessage> InsteadReceive(verify_model model) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 代收签约
		/// </summary>
		/// <returns>The receive.</returns>
		/// <param name="model">Model.</param>
		public Task<ApiResultMessage> InsteadReceive(verify_model_sms model) {
			throw new NotImplementedException();
		}

		/// <summary>
		/// 单笔代收
		/// </summary>
		/// <returns>The transfer.</returns>
		/// <param name="model">Model.</param>
		public Task<transfer_result> AgencyFund(apply_receive model) {
			throw new NotImplementedException();
		}
		#endregion

		#region 商户进件
		/// <summary>
		/// 返回的是第三方的商户号，opt：A增加，M修改
		/// </summary>
		/// <returns>The register.</returns>
		/// <param name="dto">Dto.</param>
		/// <param name="opt">A增加，M修改.</param>
		public async Task<merchant_register_result> MerchantRegister(merchant_register_model dto, string opt) {
			if (!string.IsNullOrEmpty(dto.reg_merchant_no))
				dto.open_id = dto.reg_merchant_no;
			else {
				if (string.IsNullOrEmpty(dto.bind_no))
					dto.open_id = DateTime.Now.ToUnix() + DtoHelper.RandCode(4);
				else
					dto.open_id = dto.reg_merchant_no;
			}
			var model = new hx_head_base();
			var data = new hx_apply_merchant();
			model.client_trans_id = DtoHelper.GenerateOrderNumber();
			model.trans_timestamp = DateTime.Now.ToUnix();
			data.payee_bank_id = SetMerchantBankCode(dto.bank_code);
			SetMerchantInfo(data, dto, opt);
			SetPayType(data, dto);
			model.data = data.ToJson();
			var resultApi = await _hxDataSign.PayGateway<hx_apply_merchant_result>(model);
			if (resultApi != null) {
				if (resultApi.resp_code == "000000") {
					dto.reg_merchant_no = resultApi.data.third_merchant_code;
					return ApiResultToJson.Json(new merchant_register_result { merchant_no = dto.reg_merchant_no });
				} else {
					return ApiResultToJson.Json<merchant_register_result>(resultApi.resp_msg);
				}
			}
			return ApiResultToJson.Json<merchant_register_result>("信息登记异常");
		}

		/// <summary>
		/// 新增商户进件
		/// </summary>
		/// <returns>The register.</returns>
		/// <param name="bind_id">Bind identifier.</param>
		public async Task<merchant_register_result> MerchantRegister(long bind_id, string settle_type,PayChannel channel = PayChannel.None) {
			var binder = _iMerchantService.Get(bind_id);
			var oemer = _iMerchantService.Get(binder.oem_id.Value);
			var model = new hx_head_base();
			var data = new hx_apply_merchant();
			model.client_trans_id = DtoHelper.GenerateOrderNumber();
			model.trans_timestamp = DateTime.Now.ToUnix();
			data.payee_bank_id = SetMerchantBankCode(binder.setting.auth_info.bank_code);
			SetMerchantInfo(data, binder, "A", settle_type);
			SetPayType(data, binder);
			model.data = data.ToJson();
			var resultApi = await _hxDataSign.PayGateway<hx_apply_merchant_result>(model);
			if (resultApi != null) {
				if (resultApi.resp_code == "000000") {
					var dto = binder.setting.auth_info.ToDtoObject<merchant_register_model>();
					dto.pay_channel = PayChannel.HxData;
					dto.reg_merchant_no = resultApi.data.third_merchant_code;
					dto.bind_no = binder.merchant_no;
					dto.merchant_no = oemer.merchant_no;
					_iMerchantService.MerchantChannelRegister(dto);
					return ApiResultToJson.Json(new merchant_register_result { merchant_no = resultApi.data.third_merchant_code });
				} else {
					if (resultApi.resp_msg.Contains(binder.setting.auth_info.mobile)) {
						var dto = binder.setting.auth_info.ToDtoObject<merchant_register_model>();
						dto.pay_channel = PayChannel.HxData;
						dto.reg_mobile = 130 + DtoHelper.RandCode(8);
						dto.bind_no = binder.merchant_no;
						dto.reg_merchant_no = binder.merchant_no;
						dto.merchant_no = oemer.merchant_no;
                        var binder_payments = _iMerchantService.GetPayments(binder.id);
                        var payment = binder_payments.FirstOrDefault(c => c.payment.channel == PayChannel.HxData);
						var settle = payment.settles.First(c => c.code == "UNIONPAY" && c.settle_type == "T0");
						dto.fee = settle.fee;
						dto.settle = ((int)(settle.settle * 100)).ToString();
						dto.settle_type = settle_type;
						var api = await MerchantRegister(dto, "A");
						if (api.result_code == 1000) {
							dto.reg_merchant_no = api.merchant_no;
							_iMerchantService.MerchantChannelRegister(dto);
							return ApiResultToJson.Json(new merchant_register_result { merchant_no = api.merchant_no });
						}
						return ApiResultToJson.Json<merchant_register_result>(api.result_msg);
					}
					return ApiResultToJson.Json<merchant_register_result>(resultApi.resp_msg);
				}
			}
			return ApiResultToJson.Json<merchant_register_result>("信息登记异常");
		}

		/// <summary>
		/// 编辑商户进件
		/// </summary>
		/// <returns>The modify.</returns>
		/// <param name="bind_id">Bind identifier.</param>
		public async Task<merchant_register_result> MerchantModify(long bind_id, string settle_type,PayChannel channel = PayChannel.None) {
			var binder = _iMerchantService.Get(bind_id);
			var oemer = _iMerchantService.Get(binder.oem_id.Value);
			var model = new hx_head_base();
			var data = new hx_apply_merchant();
			model.client_trans_id = DtoHelper.GenerateOrderNumber();
			model.trans_timestamp = DateTime.Now.ToUnix();
			data.payee_bank_id = SetMerchantBankCode(binder.setting.auth_info.bank_code);
			SetMerchantInfo(data, binder, "M", settle_type);
			SetPayType(data, binder);
			model.data = data.ToJson();
			var resultApi = await _hxDataSign.PayGateway<hx_apply_merchant_result>(model);
			if (resultApi != null) {
				if (resultApi.resp_code == "000000") {
					var dto = binder.setting.auth_info.ToDtoObject<merchant_register_model>();
					dto.pay_channel = PayChannel.HxData;
					dto.reg_merchant_no = resultApi.data.third_merchant_code;
					dto.bind_no = binder.merchant_no;
					dto.merchant_no = oemer.merchant_no;
					_iMerchantService.MerchantChannelRegister(dto);
					return ApiResultToJson.Json(new merchant_register_result { merchant_no = resultApi.data.third_merchant_code });
				} else {
					return ApiResultToJson.Json<merchant_register_result>(resultApi.resp_msg);
				}
			}
			return ApiResultToJson.Json<merchant_register_result>("信息登记异常");
		}

		/// <summary>
		/// 设置商户信息
		/// </summary>
		/// <param name="model"></param>
		/// <param name="binder"></param>
		private void SetMerchantInfo(hx_apply_merchant model, merchant_dto binder, string merchant_oper_flag, string settle_type) {
            var binder_registers = _iMerchantService.GetRegisters(binder.id);
            var authinfo2 = binder_registers.FirstOrDefault(c => c.pay_channel == PayChannel.HxData && c.settle_type == settle_type);
			if (merchant_oper_flag == "M" && authinfo2 != null) {
				model.merchant_code = authinfo2.merchant_no;
				//var regions = _iRegionService.GetRegionNames(authinfo2.region_id).Split(' ');
				//model.merchant_province = regions[0];
				//model.merchant_city = regions.Length > 1 ? regions[1] : regions[0];
				//model.merchant_address = model.merchant_province + model.merchant_city;
				//model.merchant_name = authinfo2.account_name;
				//model.merchant_code = authinfo2.merchant_no;
				//model.family_name = authinfo2.account_name;
				//model.id_card = authinfo2.id_card;
				//model.mobile = authinfo2.mobile;
				////model.mobile = 130 + DtoHelper.RandCode(8);
				//model.payee_bank_no = authinfo2.account_no;
				//model.payee_bank_name = authinfo2.bank_name;
				//model.payee_branch_code = !string.IsNullOrEmpty(authinfo2.branch_code) ? authinfo2.branch_code : model.payee_bank_id;
				//model.payee_branch_name = !string.IsNullOrEmpty(authinfo2.branch_name) ? authinfo2.branch_name : "";
				//model.payee_bank_province = model.merchant_province;
				//model.payee_bank_city = model.merchant_city;
				//model.merchant_oper_flag = merchant_oper_flag;
			} else {
				model.merchant_code = binder.merchant_no;
			}
			var authinfo = binder.setting.auth_info;
			model.merchant_name = authinfo.account_name;
			model.merchant_province = authinfo.province;
			model.merchant_city = authinfo.city;
			model.merchant_address = authinfo.province + authinfo.city;
			model.family_name = authinfo.account_name;
			model.id_card = authinfo.id_card;
			model.mobile = authinfo.mobile;
			//model.mobile = 130 + DtoHelper.RandCode(8);
			model.payee_bank_no = authinfo.account_no;
			model.payee_bank_name = authinfo.bank_name;
			model.payee_branch_code = !string.IsNullOrEmpty(authinfo.branch_code) ? authinfo.branch_code : model.payee_bank_id;
			model.payee_branch_name = !string.IsNullOrEmpty(authinfo.branch_name) ? authinfo.branch_name : "";
			model.payee_bank_province = authinfo.province;
			model.payee_bank_city = authinfo.city;
			model.merchant_oper_flag = merchant_oper_flag;
		}

		private void SetMerchantInfo(hx_apply_merchant model, merchant_register_model authinfo, string merchant_oper_flag) {
			model.merchant_name = authinfo.account_name;
			model.merchant_code = authinfo.open_id;
			var regions = _iRegionService.GetRegionNames(authinfo.region_id).Split(' ');
			model.merchant_province = regions[0];
			model.merchant_city = regions.Length > 1 ? regions[1] : regions[0];
			model.merchant_address = model.merchant_province + model.merchant_city;
			model.family_name = authinfo.account_name;
			model.id_card = authinfo.id_card;
			if (!string.IsNullOrEmpty(authinfo.reg_mobile))
				model.mobile = authinfo.reg_mobile;
			else
				model.mobile = authinfo.mobile;
			//model.mobile = 130 + DtoHelper.RandCode(8);
			model.payee_bank_no = authinfo.account_no;
			model.payee_bank_name = authinfo.bank_name;
			model.payee_branch_code = !string.IsNullOrEmpty(authinfo.branch_code) ? authinfo.branch_code : model.payee_bank_id;
			model.payee_branch_name = !string.IsNullOrEmpty(authinfo.branch_name) ? authinfo.branch_name : "";
			model.payee_bank_province = model.merchant_province;
			model.payee_bank_city = model.merchant_city;
			model.merchant_oper_flag = merchant_oper_flag;
		}

		private string SetMerchantBankCode(string bank_code) {
			var banks = new Dictionary<string, string>();
			banks.Add("ABC", "103100000026");
			banks.Add("BCM", "301290000007");
			banks.Add("BOC", "104100000004");
			banks.Add("CCB", "105100000017");
			banks.Add("CEB", "303100000006");
			banks.Add("CGB", "306331003281");
			banks.Add("CIB", "309391000011");
			banks.Add("CITIC", "302100011000");
			banks.Add("CMB", "308584000013");
			banks.Add("CMBC", "305100000013");
			banks.Add("HXB", "304100040000");
			banks.Add("ICBC", "102100099996");
			banks.Add("PSBC", "403100000004");
			banks.Add("SPDB", "310290000013");
			banks.Add("PAB", "307584007998");
			return banks[bank_code];
		}

		private void SetPayType(hx_apply_merchant model, merchant_dto binber) {
            var binber_payments = _iMerchantService.GetPayments(binber.id);
            var payment = binber_payments.FirstOrDefault(c => c.payment.channel == PayChannel.HxData);
			var settle = payment.settles.First(c => c.code == "UNIONPAY" && c.settle_type == "T0");
			model.rate_t0 = (settle.fee * 100).ToString("0.00");
			model.counter_fee_t0 = ((int)(settle.settle * 100)).ToString();
		}

		private void SetPayType(hx_apply_merchant model, merchant_register_model user) {
			model.rate_t0 = (user.fee * 100).ToString("0.00");
			model.counter_fee_t0 = user.settle;
		}
		#endregion

		#region 对账
		public async Task<int> ItpToFile(DateTime create_date) {
			var model = new hx_head_base();
			var data = new hx_itp_model();
			model.client_trans_id = DtoHelper.GenerateOrderNumber();
			model.trans_timestamp = DateTime.Now.ToUnix();
			data.trans_date = create_date.ToString("yyyyMMdd");
			model.data = data.ToJson();
			var resultApi = await _hxDataSign.PayGateway2(model);
			if (resultApi != null) {
				if (resultApi.resp_code == "000000") {
					string batchFileName = data.trans_date + ".txt";
					var fileName = IOHelper.GetMapPath("HX", data.trans_date, batchFileName);
					UTF8Encoding utf8 = new UTF8Encoding(false);
					using (StreamWriter sw = new StreamWriter(fileName, false, utf8)) {
						sw.WriteLine(resultApi.data);
						sw.Close();
						sw.Dispose();
					}
					var result = _iProfitDayService.Insert(new profit_day_dto {
						create_date = create_date, file = batchFileName, status = 1, pay_channel = PayChannel.HxData
					});
					return result;
				} else {
					return 0;
				}
			}
			return 0;
		}

		public int DealItp(long id) {
			var model = _iProfitDayService.Get(id);
			var strfile = model.file.Split('.')[0];
			var localFile = IOHelper.GetMapPath("HX", strfile, model.file);
			string text = "";
			UTF8Encoding utf8 = new UTF8Encoding(false);
			//快捷
			using (StreamReader sr = new StreamReader(localFile, utf8, false)) {
				text = sr.ReadToEnd();
				sr.Close();
				sr.Dispose();
			}
			var lines = text.ToObject<hx_itp_result>();
			decimal pay_amount = 0;
			decimal fee_cost = 0;
			decimal off_amount = 0;
			var kj_dic = new List<itp_model>();
			foreach (var row in lines.bills) {
				var arrs = row.Split('|');
				var pay_state = arrs[2];
				if (pay_state == "2") {
					var transaction_no = arrs[1];
					var amt = decimal.Parse(arrs[3]) / 100;
					pay_amount += amt;
					var off_amt = decimal.Parse(arrs[9]) / 100;
					off_amount += off_amt;
					var fee_amt = 0;
					//var fee_amt = decimal.Parse(arrs[8]);
					//fee_cost += fee_amt;
					kj_dic.Add(new itp_model {
						transaction_no = transaction_no, cost_fee_amt = fee_amt,
						tran_amount = amt, off_amount = off_amt
					});
				}
			}
			model.pay_amount = pay_amount;
			model.off_amount = off_amount;
			model.fee_cost = fee_cost;
			model.status = 2;
			var result = _iBillService.ChargeAccount(kj_dic, new Dictionary<string, decimal>(), PayChannel.HxData, "UNIONPAY", model);
			return result;
		}
		#endregion

		#region 四要素
		/// <summary>
		/// 四要素
		/// </summary>
		/// <returns>The verify.</returns>
		/// <param name="dto">Model.</param>
		public async Task<certify_verify_result> CertifyVerify(certify_verify dto) {
#if DEBUG
			return ApiResultToJson.Json("认证成功", new certify_verify_result { status = AuthStatusEnum.Auth });
#else
			var model = new hx_head_base();
			model.client_trans_id = DtoHelper.GenerateOrderNumber();
			model.trans_timestamp = DateTime.Now.ToUnix();
			if (dto.verify_type == "0030") {
				model.trans_type = "REALNAME_AUTH3";
				var data = new hx_certify_verify { bank_no = dto.account_no, family_name = dto.account_name, id_card = dto.id_card };
				model.data = data.ToJson();
			} else {
				model.trans_type = "REALNAME_AUTH4";
				var data = new hx_certify_verify4 { mobile = dto.mobile, bank_no = dto.account_no, family_name = dto.account_name, id_card = dto.id_card };
				model.data = data.ToJson();
			}
			var resultApi = await _hxDataSign.PayGateway<hx_apply_merchant_result>(model);
			if (resultApi != null) {
				if (resultApi.resp_code == "000000") {
					dto.status = CertifyStatus.Auth;
					_iMerchantService.CertifyVerify(dto, resultApi.resp_msg);
					return ApiResultToJson.Json("认证成功", new certify_verify_result { status = AuthStatusEnum.Auth });
				} else {
					dto.status = CertifyStatus.Fail;
					_iMerchantService.CertifyVerify(dto, resultApi.resp_msg);
					return ApiResultToJson.Json(resultApi.resp_msg, new certify_verify_result { status = AuthStatusEnum.Fail });
				}
			}
			return ApiResultToJson.Json("认证失败", new certify_verify_result { status = AuthStatusEnum.Wait });
#endif
		}

		public Task<mall_result> MallPay(mall_model obj) {
			throw new NotImplementedException();
		}

        public Task<transfer_result> TokenTransfer(long id) {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TokenTransferQuery(transfer_query model) {
            throw new NotImplementedException();
        }
        #endregion
    }
}
